home *** CD-ROM | disk | FTP | other *** search
/ Windows Game Programming for Dummies (2nd Edition) / WinGamProgFD.iso / pc / DirectX SDK / DXSDK / samples / Multimedia / Direct3D / Tutorials / Tut03_Matrices / Matrices.cpp next >
Encoding:
C/C++ Source or Header  |  2001-10-31  |  9.8 KB  |  282 lines

  1. //-----------------------------------------------------------------------------
  2. // File: Matrices.cpp
  3. //
  4. // Desc: Now that we know how to create a device and render some 2D vertices,
  5. //       this tutorial goes the next step and renders 3D geometry. To deal with
  6. //       3D geometry we need to introduce the use of 4x4 matrices to transform
  7. //       the geometry with translations, rotations, scaling, and setting up our
  8. //       camera.
  9. //
  10. //       Geometry is defined in model space. We can move it (translation),
  11. //       rotate it (rotation), or stretch it (scaling) using a world transform.
  12. //       The geometry is then said to be in world space. Next, we need to
  13. //       position the camera, or eye point, somewhere to look at the geometry.
  14. //       Another transform, via the view matrix, is used, to position and
  15. //       rotate our view. With the geometry then in view space, our last
  16. //       transform is the projection transform, which "projects" the 3D scene
  17. //       into our 2D viewport.
  18. //
  19. //       Note that in this tutorial, we are introducing the use of D3DX, which
  20. //       is a set of helper utilities for D3D. In this case, we are using some
  21. //       of D3DX's useful matrix initialization functions. To use D3DX, simply
  22. //       include <d3dx8.h> and link with d3dx8.lib.
  23. //
  24. // Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
  25. //-----------------------------------------------------------------------------
  26. #include <d3dx8.h>
  27. #include <mmsystem.h>
  28.  
  29.  
  30.  
  31.  
  32. //-----------------------------------------------------------------------------
  33. // Global variables
  34. //-----------------------------------------------------------------------------
  35. LPDIRECT3D8             g_pD3D       = NULL; // Used to create the D3DDevice
  36. LPDIRECT3DDEVICE8       g_pd3dDevice = NULL; // Our rendering device
  37. LPDIRECT3DVERTEXBUFFER8 g_pVB        = NULL; // Buffer to hold vertices
  38.  
  39. // A structure for our custom vertex type
  40. struct CUSTOMVERTEX
  41. {
  42.     FLOAT x, y, z;      // The untransformed, 3D position for the vertex
  43.     DWORD color;        // The vertex color
  44. };
  45.  
  46. // Our custom FVF, which describes our custom vertex structure
  47. #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE)
  48.  
  49.  
  50.  
  51.  
  52. //-----------------------------------------------------------------------------
  53. // Name: InitD3D()
  54. // Desc: Initializes Direct3D
  55. //-----------------------------------------------------------------------------
  56. HRESULT InitD3D( HWND hWnd )
  57. {
  58.     // Create the D3D object.
  59.     if( NULL == ( g_pD3D = Direct3DCreate8( D3D_SDK_VERSION ) ) )
  60.         return E_FAIL;
  61.  
  62.     // Get the current desktop display mode, so we can set up a back
  63.     // buffer of the same format
  64.     D3DDISPLAYMODE d3ddm;
  65.     if( FAILED( g_pD3D->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3ddm ) ) )
  66.         return E_FAIL;
  67.  
  68.     // Set up the structure used to create the D3DDevice
  69.     D3DPRESENT_PARAMETERS d3dpp;
  70.     ZeroMemory( &d3dpp, sizeof(d3dpp) );
  71.     d3dpp.Windowed = TRUE;
  72.     d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
  73.     d3dpp.BackBufferFormat = d3ddm.Format;
  74.  
  75.     // Create the D3DDevice
  76.     if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
  77.                                       D3DCREATE_SOFTWARE_VERTEXPROCESSING,
  78.                                       &d3dpp, &g_pd3dDevice ) ) )
  79.     {
  80.         return E_FAIL;
  81.     }
  82.  
  83.     // Turn off culling, so we see the front and back of the triangle
  84.     g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
  85.  
  86.     // Turn off D3D lighting, since we are providing our own vertex colors
  87.     g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
  88.  
  89.     return S_OK;
  90. }
  91.  
  92.  
  93.  
  94.  
  95. //-----------------------------------------------------------------------------
  96. // Name: InitGeometry()
  97. // Desc: Creates the scene geometry
  98. //-----------------------------------------------------------------------------
  99. HRESULT InitGeometry()
  100. {
  101.     // Initialize three vertices for rendering a triangle
  102.     CUSTOMVERTEX g_Vertices[] =
  103.     {
  104.         { -1.0f,-1.0f, 0.0f, 0xffff0000, },
  105.         {  1.0f,-1.0f, 0.0f, 0xff0000ff, },
  106.         {  0.0f, 1.0f, 0.0f, 0xffffffff, },
  107.     };
  108.  
  109.     // Create the vertex buffer.
  110.     if( FAILED( g_pd3dDevice->CreateVertexBuffer( 3*sizeof(CUSTOMVERTEX),
  111.                                                   0, D3DFVF_CUSTOMVERTEX,
  112.                                                   D3DPOOL_DEFAULT, &g_pVB ) ) )
  113.     {
  114.         return E_FAIL;
  115.     }
  116.  
  117.     // Fill the vertex buffer.
  118.     VOID* pVertices;
  119.     if( FAILED( g_pVB->Lock( 0, sizeof(g_Vertices), (BYTE**)&pVertices, 0 ) ) )
  120.         return E_FAIL;
  121.     memcpy( pVertices, g_Vertices, sizeof(g_Vertices) );
  122.     g_pVB->Unlock();
  123.  
  124.     return S_OK;
  125. }
  126.  
  127.  
  128.  
  129.  
  130. //-----------------------------------------------------------------------------
  131. // Name: Cleanup()
  132. // Desc: Releases all previously initialized objects
  133. //-----------------------------------------------------------------------------
  134. VOID Cleanup()
  135. {
  136.     if( g_pVB != NULL )
  137.         g_pVB->Release();
  138.  
  139.     if( g_pd3dDevice != NULL )
  140.         g_pd3dDevice->Release();
  141.  
  142.     if( g_pD3D != NULL )
  143.         g_pD3D->Release();
  144. }
  145.  
  146.  
  147.  
  148. //-----------------------------------------------------------------------------
  149. // Name: SetupMatrices()
  150. // Desc: Sets up the world, view, and projection transform matrices.
  151. //-----------------------------------------------------------------------------
  152. VOID SetupMatrices()
  153. {
  154.     // For our world matrix, we will just rotate the object about the y-axis.
  155.     D3DXMATRIX matWorld;
  156.     D3DXMatrixRotationY( &matWorld, timeGetTime()/150.0f );
  157.     g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
  158.  
  159.     // Set up our view matrix. A view matrix can be defined given an eye point,
  160.     // a point to lookat, and a direction for which way is up. Here, we set the
  161.     // eye five units back along the z-axis and up three units, look at the
  162.     // origin, and define "up" to be in the y-direction.
  163.     D3DXMATRIX matView;
  164.     D3DXMatrixLookAtLH( &matView, &D3DXVECTOR3( 0.0f, 3.0f,-5.0f ),
  165.                                   &D3DXVECTOR3( 0.0f, 0.0f, 0.0f ),
  166.                                   &D3DXVECTOR3( 0.0f, 1.0f, 0.0f ) );
  167.     g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );
  168.  
  169.     // For the projection matrix, we set up a perspective transform (which
  170.     // transforms geometry from 3D view space to 2D viewport space, with
  171.     // a perspective divide making objects smaller in the distance). To build
  172.     // a perpsective transform, we need the field of view (1/4 pi is common),
  173.     // the aspect ratio, and the near and far clipping planes (which define at
  174.     // what distances geometry should be no longer be rendered).
  175.     D3DXMATRIX matProj;
  176.     D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, 1.0f, 1.0f, 100.0f );
  177.     g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
  178. }
  179.  
  180.  
  181.  
  182. //-----------------------------------------------------------------------------
  183. // Name: Render()
  184. // Desc: Draws the scene
  185. //-----------------------------------------------------------------------------
  186. VOID Render()
  187. {
  188.     // Clear the backbuffer to a black color
  189.     g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.0f, 0 );
  190.  
  191.     // Begin the scene
  192.     g_pd3dDevice->BeginScene();
  193.  
  194.     // Setup the world, view, and projection matrices
  195.     SetupMatrices();
  196.  
  197.     // Render the vertex buffer contents
  198.     g_pd3dDevice->SetStreamSource( 0, g_pVB, sizeof(CUSTOMVERTEX) );
  199.     g_pd3dDevice->SetVertexShader( D3DFVF_CUSTOMVERTEX );
  200.     g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 1 );
  201.  
  202.     // End the scene
  203.     g_pd3dDevice->EndScene();
  204.  
  205.     // Present the backbuffer contents to the display
  206.     g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
  207. }
  208.  
  209.  
  210.  
  211.  
  212. //-----------------------------------------------------------------------------
  213. // Name: MsgProc()
  214. // Desc: The window's message handler
  215. //-----------------------------------------------------------------------------
  216. LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
  217. {
  218.     switch( msg )
  219.     {
  220.         case WM_DESTROY:
  221.             PostQuitMessage( 0 );
  222.             return 0;
  223.     }
  224.  
  225.     return DefWindowProc( hWnd, msg, wParam, lParam );
  226. }
  227.  
  228.  
  229.  
  230.  
  231. //-----------------------------------------------------------------------------
  232. // Name: WinMain()
  233. // Desc: The application's entry point
  234. //-----------------------------------------------------------------------------
  235. INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
  236. {
  237.     // Register the window class
  238.     WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,
  239.                       GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
  240.                       "D3D Tutorial", NULL };
  241.     RegisterClassEx( &wc );
  242.  
  243.     // Create the application's window
  244.     HWND hWnd = CreateWindow( "D3D Tutorial", "D3D Tutorial 03: Matrices",
  245.                               WS_OVERLAPPEDWINDOW, 100, 100, 256, 256,
  246.                               GetDesktopWindow(), NULL, wc.hInstance, NULL );
  247.  
  248.     // Initialize Direct3D
  249.     if( SUCCEEDED( InitD3D( hWnd ) ) )
  250.     {
  251.         // Create the scene geometry
  252.         if( SUCCEEDED( InitGeometry() ) )
  253.         {
  254.             // Show the window
  255.             ShowWindow( hWnd, SW_SHOWDEFAULT );
  256.             UpdateWindow( hWnd );
  257.  
  258.             // Enter the message loop
  259.             MSG msg;
  260.             ZeroMemory( &msg, sizeof(msg) );
  261.             while( msg.message!=WM_QUIT )
  262.             {
  263.                 if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
  264.                 {
  265.                     TranslateMessage( &msg );
  266.                     DispatchMessage( &msg );
  267.                 }
  268.                 else
  269.                     Render();
  270.             }
  271.         }
  272.     }
  273.  
  274.     // Clean up everything and exit the app
  275.     Cleanup();
  276.     UnregisterClass( "D3D Tutorial", wc.hInstance );
  277.     return 0;
  278. }
  279.  
  280.  
  281.  
  282.